#include "ChickenDefGame.h"
#include "stdafx.h"
#include "ResourceManagers.h"
#include "GUIOverlay.h"
#include "ComboSystem.h"
#include <sstream>

using namespace sf;
enum GameState{PLAYING, GAMEOVER};

ChickenDefGame::ChickenDefGame(void)
{
	wnd= new RenderWindow(VideoMode(800,600),"Chicken Defense");

	//load background

	m_sprBack.SetImage(*ImageManager::Instance()->GetImage("background.png"));
	//load gameover screen
	m_sprGameOver.SetImage(*ImageManager::Instance()->GetImage("gameover_new.png"));
	m_sprGameOver.SetPosition(200,200);

	//Create chickens
	m_control_p1=new KeyboardControl(*wnd,sf::Key::W,sf::Key::S,sf::Key::A,sf::Key::D,sf::Key::C,sf::Key::V );
	m_Player1= new Chicken(wnd, m_control_p1, this);
	m_control_p2=new KeyboardControl(*wnd,sf::Key::Up,sf::Key::Down,sf::Key::Left,sf::Key::Right,sf::Key::O,sf::Key::P);
	m_Player2= new Chicken(wnd, m_control_p2, this);

	srand(time(NULL));

	for(int i=0;i<m_maxWeasels;++i){
		Weasel* w= new Weasel(this);
		m_weasels.push_back(w);
	}
	for(int i=0;i<m_maxEggs;++i){
		m_eggs.push_back(new Egg(this));
	}

    nest=Nest::Instance();
	//load music
	theme.OpenFromFile("Theme.ogg");
	gameOverSound.SetBuffer(*SoundBufferManager::Instance()->GetBuffer("game_Over.wav"));

	Nest::Instance()->SetGame(this);

	Reset();



}

void ChickenDefGame::Reset(){

	theme.Stop();
	theme.SetLoop(true);
	theme.Play();

	timePlayed=0.0f;
	timeSinceLastWeasel=0.0f;
	//GUIOverlay::Instance()->ShowChangeText(10);
	nest->Reset();

	m_NWeasels=1;

	for(int i=0;i<m_NWeasels;++i)
		m_weasels[i]->Reset();
	for(int i=m_NWeasels;i<m_maxWeasels;++i)
		m_weasels[i]->SilentDeath();

	for(int i=0;i<m_maxEggs;++i)
		m_eggs[i]->Destroy();

	//maaaaso
	timeToSwitch=(float)(rand()%5+15);
	timeElapsed=timeToSwitch;
	GUIOverlay::Instance()->SetTotalTimeToSwitch(timeToSwitch);

	//seteamos cual arranca empoalgo
	if(rand()%2==0){
		nest->SetChicken(m_Player1);
		m_Player1->GotoGallina();
		m_Player2->GotoPollito();
		GUIOverlay::Instance()->SetPlayerHatching(1);
	}
	else{
		nest->SetChicken(m_Player2);
		m_Player2->GotoGallina();
		m_Player1->GotoPollito();
		GUIOverlay::Instance()->SetPlayerHatching(2);
	}

	m_Player1->Reset(wnd);
	m_Player2->Reset(wnd);

	gamestate=PLAYING;
}

ChickenDefGame::~ChickenDefGame(void){
    delete m_Player1;
    delete m_control_p1;
	delete m_Player2;
    delete m_control_p2;
    delete wnd;
}

bool ChickenDefGame::ProcessEvents(){

	while (wnd->GetEvent(evt)){

		switch(evt.Type){

            case Event::Closed:
                wnd->Close();
                return false;
			break;

			case Event::KeyPressed:
				if((gamestate==GAMEOVER)&&(evt.Key.Code==Key::Return))
					Reset();

		}


	}

	return true;

}
void ChickenDefGame::UpdateWeasels(){
	int alives=0;

	for(int i=0;i<m_maxWeasels;++i){
		if(m_weasels[i]->IsAlive()){
			m_weasels[i]->Update(wnd->GetFrameTime());
			alives++;
		}
	}

	//si hay menos vivas de las que deberia levantamos hasta que
	//lleguen al numero debido
	int i=0;
	while(alives<m_NWeasels){
		if(!m_weasels[i]->IsAlive()){
			m_weasels[i]->Reset();
			alives++;
			}
		++i;
	}
}

void ChickenDefGame::UpdateEggs(){

	for(int i=0;i<m_maxEggs;++i)
		if(m_eggs[i]->IsActive())
			m_eggs[i]->Update();

}

void ChickenDefGame::DrawEggs(){

	for(int i=0;i<m_maxEggs;++i){
		if(m_eggs[i]->IsActive())
			m_eggs[i]->Draw(wnd);
	}
}

void ChickenDefGame::GameOver(){

	gameOverSound.Play();
	gamestate=GAMEOVER;


}

void ChickenDefGame::DrawWeasels(){

	for(int i=0;i<m_maxWeasels;++i)
		if(m_weasels[i]->IsAlive())
			m_weasels[i]->Draw(wnd);

}

bool ChickenDefGame::OutOfBounds(Vector2f p){

	if ( (p.x> 800) || (p.x < 0) || (p.y<0) || (p.y>600))
		return true;

	return false;

}


//Cambia la gallina que puede acceder al nido
void ChickenDefGame::ChangeRoles(){
	if(nest->GetChicken()==m_Player1){
		nest->SetChicken(m_Player2);
		m_Player1->GotoPollito();
		m_Player1->LeaveNest();
		m_Player2->GotoGallina();
		GUIOverlay::Instance()->SetPlayerHatching(2);
	}

	else{
		nest->SetChicken(m_Player1);
		m_Player2->GotoPollito();
		m_Player2->LeaveNest();
		m_Player1->GotoGallina();

		GUIOverlay::Instance()->SetPlayerHatching(1);
	}
}
Weasel* ChickenDefGame::CircleCollidesWithWeasels(Vector2f center, float r){


	for(int i=0;i<m_maxWeasels;++i){
		if(!m_weasels[i]->IsAlive())
			continue;

		Vector2f pos= m_weasels[i]->GetCenter();

		float norm= sqrtf((pos.x - center.x)*(pos.x - center.x)+(pos.y - center.y)*(pos.y - center.y));
		if (norm< (r+m_weasels[i]->GetCircleRadius()) ){
			return m_weasels[i];

		}

	}
	return NULL;

}

Egg* ChickenDefGame::GetEgg(){

	int i=0;

	while(m_eggs[i]->IsActive())
		i++;

	return m_eggs[i];
}

#include <cstdio>
using namespace std;

void ChickenDefGame::UpdateSwitch(float dt){
	timeElapsed-=dt;
//	sprintf(time,"Change:%.2f",timeElapsed);
	GUIOverlay::Instance()->SetTimeToSwitch(timeElapsed);
	if(timeElapsed<=0){
		ChangeRoles();
		GUIOverlay::Instance()->ShowChangeText(1.5f);
		timeToSwitch=(float)(rand()%5+15);
		timeElapsed=timeToSwitch;
	}

}

void ChickenDefGame::Loop(){

	wnd->Show(true);
    float elapsedTime;

	while(wnd->IsOpened()){

		if(!ProcessEvents())
			return;

		if(gamestate!=GAMEOVER){


			// maneja la entrada
			m_control_p1->Update();
			m_control_p2->Update();

			// calcula el tiempo
			elapsedTime=wnd->GetFrameTime();

			timePlayed+=elapsedTime;
			timeSinceLastWeasel+=elapsedTime;
			if(timeSinceLastWeasel>25){
				timeSinceLastWeasel=0;
				m_NWeasels=min(10,++m_NWeasels);
			}

			//convert to string

			GUIOverlay::Instance()->SetElapsedTime(timePlayed);


			// actualiza los jugadores
			m_Player1->Update(elapsedTime);
			m_Player2->Update(elapsedTime);

			UpdateWeasels();
			UpdateEggs();
			nest->Update(elapsedTime);
			UpdateSwitch(elapsedTime);
			ComboSystem::Instance()->Update(elapsedTime);
			GUIOverlay::Instance()->Update(elapsedTime);


		}


		// actualiza la pantalla
		wnd->Clear();
		wnd->Draw(m_sprBack);
		wnd->Draw(*nest);
		DrawEggs();
		wnd->Draw(*m_Player1);
		wnd->Draw(*m_Player2);
		DrawWeasels();
		ComboSystem::Instance()->Draw(wnd);

		GUIOverlay::Instance()->Draw(wnd);

		if(gamestate==GAMEOVER)
			wnd->Draw(m_sprGameOver);

		wnd->Display();



	}//end while



}
